<?php

/**
 * mForge Framework
 *
 * LICENSE:
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * The license is bundled with this package in the file LICENSE.txt.
 * You may also obtain a copy of the License at this URL:
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @copyright  Copyright (c) 2011, Jonathan Hedrén
 * @author     Jonathan Hedrén <jonathan.hedren@gmail.com>
 * @license    http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

namespace mForge\Modules\Authentication;

/**
 * A basic authentication class.
 */
class Auth {

    const SESSION_AUTHENTICATED_KEY = 'session_authenticated_key';
    const SESSION_LIFETIME_KEY      = 'session_lifetime_key';

    /**
     * The lifetime of the authentication session.
     *
     * @var integer
     */
    private $lifetime = 1800;
    
    /**
     *
     * @var \mForge\Modules\Users\UserService
     */
    private $userService;

    /**
     *
     * @var Session
     */
    private $session;

    /**
     *
     * @param \mForge\Modules\Users\UserService $userService
     * @param \mForge\Modules\Session\Session $session
     * @param integer $lifeTime
     */
    public function  __construct(\mForge\Modules\Users\UserService $userService, \mForge\Modules\Session\Session $session, $lifeTime)
    {
        $this->userService = $userService;
        $this->session = $session;
        $this->lifeTime = (int) $lifeTime;
    }

    /**
     * Authenticates a user by providing the password and the string to match
     * against. This method will NOT set any user data to the session.
     *
     * @param string $password
     * @param string $match
     * @return boolean
     */
    public function authenticate($password, $match)
    {
        $hashedPassword = $this->userService->generatePasswordHash($password);
        
        if ($hashedPassword == $match) {
            $this->session->regenerateId();
            $this->session->set(self::SESSION_AUTHENTICATED_KEY, true);
            $this->session->set(self::SESSION_LIFETIME_KEY, time() + $this->lifetime);

            return true;
        }

        return false;
    }

    /**
     * Clears the authentication session.
     * 
     * @return void
     */
    public function clearAuthentication()
    {
        $this->session->set(self::SESSION_AUTHENTICATED_KEY, null);
        $this->session->set(self::SESSION_LIFETIME_KEY, null);
        $this->session->regenerateId();
    }

    /**
     * Checks the authentication session.
     *
     * Differs from the isAuthenticated method by not checking if the session
     * is expired.
     *
     * @return boolean
     */
    public function hasIdentity()
    {
        if ($this->session->get(self::SESSION_AUTHENTICATED_KEY) === null
            || !$this->session->get(self::SESSION_AUTHENTICATED_KEY)) {
                return false;
        }
        return true;
    }

    /**
     * Checks the authentication session. If authenticated, the session lifetime
     * will be updated.
     *
     * @return boolean
     */
    public function isAuthenticated()
    {
        if (time() > $this->session->get(self::SESSION_LIFETIME_KEY)) {
            return false;
        }
        if ($this->session->get(self::SESSION_AUTHENTICATED_KEY) === null
            || !$this->session->get(self::SESSION_AUTHENTICATED_KEY)) {
                return false;
        }
        $this->session->set(self::SESSION_LIFETIME_KEY, time() + $this->lifetime);
        return true;
    }

    /**
     * Sets the lifetime of the authentication session.
     *
     * @param integer $lifeTime
     * @return void
     */
    public function setLifetime($lifeTime)
    {
        $this->lifetime = (int) $lifeTime;
    }
}
